package nexus.com.date
{
	import com.ux.util.NumberUtil;
	
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	
	import nexus.base.NXSprite;
	import nexus.com.button.Button;
	import nexus.com.date.DateItem;
	import nexus.event.CalendarEvent;
	import nexus.com.date.DateUtil;
	import nexus.com.date.DateVO;
	
	
	[Event(name="viewMonthChange", type="nexus.event.CalendarEvent")]
	[Event(name="selectedDateChange", type="nexus.event.CalendarEvent")]
	
	
	/**
	 * <br>설명 : </br> 
	 * @author winnie
	 */	
	public class Calendar extends NXSprite
	{
		//-----------------------------------------------------------------------------------
		//
		// private vars
		//
		//-----------------------------------------------------------------------------------
		
		private var _currentYear : Number = -1;
		private var _currentMonth : Number = -1;
		private var _currentYYYYMMTF : TextField;
		
		private var _selectedYear : Number = -1;
		private var _selectedMonth : Number = -1;
		private var _selectedDate : Number = -1;
		private var _dateList : Vector.<DateVO>;
		private var _dateItemList : Vector.<DateItem>;
		private var _gcItemList : Vector.<DateItem>;
		
		private var _selectDateVO : DateVO;
		private var _bgLayer : Shape;
		
		
		private var _ptXtoDayList : Array;
		private var _dayTitleList : Array;
		private var _dayTitleStrList : Array;
		private var _sundayTF : TextField;
		private var _mondayTF : TextField;
		private var _thuesdayTF : TextField;
		private var _wednesdayTF : TextField;
		private var _thursdayTF : TextField;
		private var _fridaydayTF : TextField;
		private var _saturdayTF : TextField;
		
		
		/**
		 * 일 1칸의 크기. 
		 */		
		private var _boxWidth : Number = 26;
		private var _boxHeight : Number = 19;
		
		/**
		 * 이전달, 다음달 버튼 
		 */		
		private var _prevMonthBtn : Sprite;
		private var _nextMonthBtn : Sprite;
		
		/**
		 * 캘린더의 정렬시 패딩값. 
		 */		
		private var _calendarPaddingTop : Number = 89;
		private var _calendarPaddingLeft : Number = 0;
		
		/**
		 * 이전달, 다음달 앞뒤 여백에 날짜를 포함할 것인가. 
		 */		
		private var _isContainPrevDate : Boolean = false;
		private var _isContainNextDate : Boolean = false;
		
		
		
		//-----------------------------------------------------------------------------------
		//
		// protected vars
		//
		//-----------------------------------------------------------------------------------
		
		
		//-----------------------------------------------------------------------------------
		//
		// public vars
		//
		//-----------------------------------------------------------------------------------
		
		
		
		//-----------------------------------------------------------------------------------
		//
		// constructor
		//
		//-----------------------------------------------------------------------------------
		public function Calendar()
		{
			super();
			
			_dateItemList = new Vector.<DateItem>();
			_gcItemList = new Vector.<DateItem>();
			
			// 기본적으로 현재 날짜를 셋팅
			dateList = DateUtil.getDateListAt( currentYear, currentMonth, isContainPrevDate, isContainNextDate );
			
			prevMonthBtnDefaultSetting();
			nextMonthBtnDefaultSetting();
			
			addChild( currentYYYYMMTF );
			setCurrentYYYYMM();
			
			_sundayTF = makeDayTF( 0xd84848 );
			_mondayTF = makeDayTF( 0x858585 );
			_thuesdayTF = makeDayTF( 0x858585 );
			_wednesdayTF = makeDayTF( 0x858585 );
			_thursdayTF = makeDayTF( 0x858585 );
			_fridaydayTF = makeDayTF( 0x858585 );
			_saturdayTF = makeDayTF( 0x5891e7 );
			
			_dayTitleList = [_sundayTF, _mondayTF, _thuesdayTF, _wednesdayTF, _thursdayTF, _fridaydayTF	, _saturdayTF ];
			_ptXtoDayList = [];
			
			_bgLayer = new Shape();
			addChildAt( _bgLayer, 0 );
		}
		
		//-----------------------------------------------------------------------------------
		//
		// setter / getter
		//
		//-----------------------------------------------------------------------------------
		
		
		public function get dayTitleStrList():Array
		{
			if( _dayTitleStrList == null )
			{
				_dayTitleStrList = ['S','M','T','W','T','F','S'];
			}
			return _dayTitleStrList;
		}

		public function set dayTitleStrList(value:Array):void
		{
			_dayTitleStrList = value;
		}

		public function get currentYYYYMMTF():TextField
		{
			if( _currentYYYYMMTF == null )
			{
				_currentYYYYMMTF = new TextField();
				var tf : TextFormat = new TextFormat( "돋움" );
				tf.bold = true;
				tf.color = 0x000000;
				_currentYYYYMMTF.selectable = false;
				_currentYYYYMMTF.mouseEnabled = false;
				_currentYYYYMMTF.mouseWheelEnabled = false;
				_currentYYYYMMTF.autoSize = TextFieldAutoSize.LEFT;
				_currentYYYYMMTF.defaultTextFormat = tf;
				_currentYYYYMMTF.setTextFormat( tf );
				
			}
			return _currentYYYYMMTF;
		}

		public function set currentYYYYMMTF(value:TextField):void
		{
			_currentYYYYMMTF = value;
		}

		public function get isContainNextDate():Boolean
		{
			return _isContainNextDate;
		}

		public function set isContainNextDate(value:Boolean):void
		{
			_isContainNextDate = value;
			dateList = DateUtil.getDateListAt( currentYear, currentMonth, isContainPrevDate, isContainNextDate );
		}

		public function get isContainPrevDate():Boolean
		{
			return _isContainPrevDate;
		}

		public function set isContainPrevDate(value:Boolean):void
		{
			_isContainPrevDate = value;
			dateList = DateUtil.getDateListAt( currentYear, currentMonth, isContainPrevDate, isContainNextDate );
		}

		public function get currentMonth():Number
		{
			if( _currentMonth == -1 )
			{
				_currentMonth = uint( new Date().getMonth() );
			}
			return _currentMonth;
		}

		public function set currentMonth(value:Number):void
		{
			_currentMonth = value;
		}

		public function get currentYear():Number
		{
			if( _currentYear == -1 )
			{
				_currentYear = uint( new Date().getFullYear() );
			}
			return _currentYear;
		}

		public function set currentYear(value:Number):void
		{
			_currentYear = value;
		}

		public function get calendarPaddingLeft():Number
		{
			return _calendarPaddingLeft;
		}

		public function set calendarPaddingLeft(value:Number):void
		{
			_calendarPaddingLeft = value;
		}

		public function get calendarPaddingTop():Number
		{
			return _calendarPaddingTop;
		}

		public function set calendarPaddingTop(value:Number):void
		{
			_calendarPaddingTop = value;
		}

		public function get nextMonthBtn():Sprite
		{
			if( _nextMonthBtn == null )
			{
				_nextMonthBtn = new CALENDAR_RIGHT_BTN();
				_nextMonthBtn.buttonMode = true;
			}
			
			return _nextMonthBtn;
		}

		public function set nextMonthBtn(value:Sprite):void
		{
			if( _nextMonthBtn && this.contains( _nextMonthBtn ) )
			{
				removeChild( _nextMonthBtn );
				_nextMonthBtn = null;
			}
			
			_nextMonthBtn = value;
			
			nextMonthBtnDefaultSetting();
		}
		
		
		public function get prevMonthBtn():Sprite
		{
			if( _prevMonthBtn == null )
			{
				_prevMonthBtn = new CALENDAR_LEFT_BTN();
				_prevMonthBtn.buttonMode = true;
			}
			return _prevMonthBtn;
		}

		public function set prevMonthBtn(value:Sprite):void
		{
			if( _prevMonthBtn && this.contains( _prevMonthBtn ) )
			{
				removeChild( _prevMonthBtn );
				_prevMonthBtn = null;
			}
			
			_prevMonthBtn = value;
			
			prevMonthBtnDefaultSetting();
		}
		
		
		
		
		
		public function get selectDateVO():DateVO
		{
			return _selectDateVO;
		}

		public function set selectDateVO(value:DateVO):void
		{
			_selectDateVO = value;
		}

		public function get boxHeight():Number
		{
			return _boxHeight;
		}

		public function set boxHeight(value:Number):void
		{
			_boxHeight = value;
		}

		public function get boxWidth():Number
		{
			return _boxWidth;
		}

		public function set boxWidth(value:Number):void
		{
			_boxWidth = value;
		}

		public function get selectedDate():Number
		{
			if( _selectedDate == -1  )
			{
				_selectedDate = uint( new Date().getDate() );
			}
			return _selectedDate;
		}

		public function set selectedDate(value:Number):void
		{
			_selectedDate = value;
		}

		public function get selectedMonth():Number
		{
			if( _selectedMonth == -1 )
			{
				_selectedMonth = uint( new Date().getMonth() );
			}
			return _selectedMonth;
		}
		
		public function set selectedMonth(value:Number):void
		{
			_selectedMonth = value;
		}
		
		public function get selectedYear():Number
		{
			if( _selectedYear == -1 )
			{
				_selectedYear = uint( new Date().getFullYear() );
			}
			return _selectedYear;
		}
		
		public function set selectedYear(value:Number):void
		{
			_selectedYear = value;
		}
		
		public function get dateList():Vector.<DateVO>
		{
			return _dateList;
		}
		
		public function set dateList(value:Vector.<DateVO>):void
		{
			_dateList = value;
			setDateItemList();
		}

		
		
		
		//-----------------------------------------------------------------------------------
		//
		// public function
		//
		//-----------------------------------------------------------------------------------
		
		override public function updateDisplayList():void
		{
			super.updateDisplayList();
			
			var rowNum : int = 0;
			var len:int = _dateItemList.length;
			for (var i:int = 0; i < len; i++) 
			{
				_dateItemList[ i ].setViewSize( boxWidth, boxHeight );
				_dateItemList[ i ].x = _dateItemList[ i ].vo.day * boxWidth + calendarPaddingLeft + 5;
				_dateItemList[ i ].y = rowNum * boxHeight + calendarPaddingTop;
				_dateItemList[ i ].apply();
				
				_ptXtoDayList[ _dateItemList[ i ].vo.day ] = _dateItemList[ i ].x;
				
				if( _dateItemList[ i ].vo.day == 6 ) rowNum++;
			}
			
			
			// 나중에 자동화로 바꿔야 함. ------------------------------------------
			prevMonthBtn.x = 50;
			prevMonthBtn.y = 12;
			
			currentYYYYMMTF.x = prevMonthBtn.x + prevMonthBtn.width + 10;
			currentYYYYMMTF.y = prevMonthBtn.y;
			
			nextMonthBtn.x = currentYYYYMMTF.x + currentYYYYMMTF.textWidth + 4 + 10;
			nextMonthBtn.y = prevMonthBtn.y;
			
			for( i = 0; i<7; i++ )
			{
				_dayTitleList[ i ].text = dayTitleStrList[ i ];
				_dayTitleList[ i ].x = _ptXtoDayList[ i ]+6;
				_dayTitleList[ i ].y = 51;
			}
			
			// 나중에 자동화로 바꿔야 함. ------------------------------------------
			
			
			
			var g : Graphics = _bgLayer.graphics;
			g.lineStyle( 1, 0xcccccc );
			g.moveTo( 0, 40 );
			g.lineTo( viewWidth, 40 );
			
			g.moveTo( 0, 77 );
			g.lineTo( viewWidth, 77 );
			
			g.lineStyle();
			g.beginFill(0xf6f6f6, 1 );
			g.drawRect( 0, 41, viewWidth, 36 );
			g.endFill();
			
			
			
			
			
			applyDefault();
		}
		
		//-----------------------------------------------------------------------------------
		//
		// protected function
		//
		//-----------------------------------------------------------------------------------
		
		
		
		
		//-----------------------------------------------------------------------------------
		//
		// private function
		//
		//-----------------------------------------------------------------------------------
		
		
		private function setCurrentYYYYMM():void
		{
			currentYYYYMMTF.text = String( currentYear ) + "." + String( NumberUtil.getUnitString( currentMonth+1, 2 ) );
		}		
		
		
		/**
		 * <br>요일 표시하는 텍스트필드 만들어 반환.</br>
		 * @param textfield
		 * @param color
		 * @return 
		 */		
		private function makeDayTF( color:uint ):TextField
		{
			var textfield : TextField; 
			textfield = new TextField();
			var tf : TextFormat = new TextFormat( "돋움" );
			tf.bold = true;
			tf.color = color;
			textfield.selectable = false;
			textfield.mouseEnabled = false;
			textfield.mouseWheelEnabled = false;
			textfield.defaultTextFormat = tf;
			textfield.setTextFormat( tf );
			textfield.autoSize = TextFieldAutoSize.LEFT;
			
			this.addChild( textfield );
			
			return textfield;
		}
		
		
		private function setDateItemList():void
		{
			var len:int;
			var i : int;
			var item : DateItem;
			// 우선 지난 날짜들을 쓰레기통에 담는다.
			if( _dateItemList != null && _dateItemList.length > 0 )
			{
				len = _dateItemList.length;
				for ( i=0; i < len; i++) 
				{
					item = _dateItemList.shift();
					if( this.contains( item ) ) removeChild( item );
					_gcItemList.push( item );
				}
			}
			
			
			// 현재 날짜로 다시 셋팅함.
			var d : Date = new Date();
			len = _dateList.length;
			for ( i=0; i < len; i++) 
			{
				item = getDateItem();
				item.vo = _dateList[ i ];
				
				if( item.vo.year == d.getFullYear() && item.vo.month == d.getMonth() && item.vo.date == d.getDate() )
				{
					item.isCurrentDate = true;
					selectDateVO = _dateList[ i ];
				}
				
				selectionControl();
				item.addEventListener(MouseEvent.CLICK, onDateItemClick );
				_dateItemList.push( item );
			}
		}		
		
		
		/**
		 * @return 재활용 메서드 - 날짜 아이템 반환
		 */		
		private function getDateItem():DateItem
		{
			var item : DateItem;
			if( _gcItemList.length > 0 )
			{
				item = _gcItemList.shift();
			}
			
			item = new DateItem();
			addChild( item );
			
			return item;
		}
		
		
		private function selectionControl():void
		{
			var len:int = _dateItemList.length;
			for (var i:int = 0; i < len; i++) 
			{
				if( selectDateVO == _dateItemList[ i ].vo )
				{
					_dateItemList[ i ].ON();
				}
				else
				{
					_dateItemList[ i ].OFF();
				}
			}
		}
		
		
		private function nextMonthBtnDefaultSetting():void
		{
			addChild( nextMonthBtn );
			nextMonthBtn.buttonMode = true;
			nextMonthBtn.addEventListener( MouseEvent.CLICK, onNextClick );
		}
		
		
		private function prevMonthBtnDefaultSetting():void
		{
			addChild( prevMonthBtn );
			prevMonthBtn.buttonMode = true;
			prevMonthBtn.addEventListener( MouseEvent.CLICK, onPrevClick );
		}
		
		
		//-----------------------------------------------------------------------------------
		//
		// event handler
		//
		//-----------------------------------------------------------------------------------
		protected function onNextClick(e:MouseEvent):void
		{
			if( ++currentMonth == 12 )
			{
				currentMonth = 0;
				++currentYear;
			}
			
			dateList = DateUtil.getDateListAt( currentYear, currentMonth, isContainPrevDate, isContainNextDate );
			
			var de : CalendarEvent = new CalendarEvent( CalendarEvent.VIEW_MONTH_CHANGE );
			de.year = currentYear;
			de.month = currentMonth;
			dispatchEvent( de );
			
			setCurrentYYYYMM();
			
			this.apply();
		}
		
		protected function onPrevClick(e:MouseEvent):void
		{
			if( --currentMonth == -1 )
			{
				currentMonth = 11;
				--currentYear;
			}
			dateList = DateUtil.getDateListAt( currentYear, currentMonth, isContainPrevDate, isContainNextDate );
			
			var de : CalendarEvent = new CalendarEvent( CalendarEvent.VIEW_MONTH_CHANGE );
			de.year = currentYear;
			de.month = currentMonth;
			dispatchEvent( de );
			
			setCurrentYYYYMM();
			
			this.apply();
		}
		
		protected function onDateItemClick(e:MouseEvent):void
		{
			var item : DateItem = e.currentTarget as DateItem;
			selectedYear = item.vo.year;
			selectedMonth = item.vo.month;
			selectedDate = item.vo.date;
			
			selectDateVO = item.vo;
			
			selectionControl();
			
			
			
			var de : CalendarEvent = new CalendarEvent( CalendarEvent.SELECTED_DATE_CHAGE );
			de.year = selectedYear;
			de.month = selectedMonth;
			de.date = selectedDate;
			dispatchEvent( de );
		}
		
		//-----------------------------------------------------------------------------------
		//
		// destory
		//
		//-----------------------------------------------------------------------------------
		
		override public function destory():void
		{
			super.destory();
		}
	}
}